﻿using MyWeb.ScheduledTasks.Models;
using MyWeb.ScheduledTasks.Services;
using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using System.Net;
using System.Text;

namespace MyWeb.ScheduledTasks.Business.Job
{
    public class HttpResultfulJob : IJob
    {
        readonly IHttpClientFactory httpClientFactory;
        private IJobsService _quartzService;
        public HttpResultfulJob(IHttpClientFactory httpClientFactory, IJobsService quartzService)
        {
            this.httpClientFactory = httpClientFactory;
            this._quartzService = quartzService;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            
            AbstractTrigger? trigger = (context as JobExecutionContextImpl).Trigger as AbstractTrigger;

            TaskLog log = new TaskLog();
            log.BeginDate = DateTime.Now;
            log.TaskName = trigger.Name;
            log.GroupName = trigger.Group;
            log.TaskType = 2;

            try
            {
                Jobs? jobs = _quartzService.GetJobs(a => a.TaskName == trigger.Name && a.GroupName == trigger.Group).Result.FirstOrDefault();
                if (jobs == null)
                {
                    jobs = _quartzService.GetJobs(a => a.TaskName == trigger.JobName && a.GroupName == trigger.JobGroup).Result.FirstOrDefault();
                }
                if (jobs == null)
                {
                    throw new Exception($"组别:{trigger.JobGroup}/{trigger.Group},名称:{trigger.JobName}/{trigger.Name},的作业未找到,可能已被移除", new Exception("task is not exists!"));
                }
                log.JobsId = jobs.Id;
                log.TaskName = jobs.TaskName;
                log.GroupName = jobs.GroupName;
                log.ExecTarget = jobs.ApiUrl;
                if (string.IsNullOrEmpty(jobs.ApiUrl) || jobs.ApiUrl == "/")
                {
                    throw new Exception($"组别:{trigger.JobGroup}/{trigger.Group},名称:{trigger.JobName}/{trigger.Name},参数非法或者异常!", new Exception("invalid parameter"));
                }

                string url = jobs.ApiUrl;
                //添加Url参数
                if (!string.IsNullOrEmpty(jobs.Parameter))
                {
                    Dictionary<string, string>? keys = new Dictionary<string, string>();
                    keys = JsonConvert.DeserializeObject<Dictionary<string, string>>(jobs.ApiHeader);
                    if (keys != null && keys.Count > 0)
                    {
                        if (url.Substring(url.Length - 1, 1) != "?" && !url.Contains("?"))
                        {
                            url = url + "?";
                        }
                        foreach (var h in keys)
                        {
                            url = url + $"&{h.Key}={h.Value}";
                        }
                    }
                }
                log.ExecTarget = url;
                //发送http请求
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = jobs.ApiRequestType?.ToLower() == "get" ? "GET" : "POST";
                request.ContentType = "application/json;charset=UTF-8";
                request.Timeout = 6000;
                //添加Header参数
                if (!string.IsNullOrEmpty(jobs.ApiHeader))
                {
                    Dictionary<string, string>? keys = new Dictionary<string, string>();
                    keys = JsonConvert.DeserializeObject<Dictionary<string, string>>(jobs.ApiHeader);
                    if (keys != null && keys.Count > 0)
                    {
                        foreach (var h in keys)
                        {
                            request.Headers.Add(h.Key, h.Value);
                        }
                    }
                }
                
                //添加Body参数
                if (!string.IsNullOrEmpty(jobs.ApiBody))
                {
                    log.RequestParam = jobs.ApiBody;
                    byte[] bytes = Encoding.UTF8.GetBytes(jobs.ApiBody);
                    request.ContentLength = bytes.Length;
                    Stream strStream = request.GetRequestStream();
                    strStream.Write(bytes, 0, bytes.Length);
                    strStream.Close();
                }

                //接收应答
                HttpWebResponse Response = (HttpWebResponse)request.GetResponse();
                Stream stream = Response.GetResponseStream();
                StreamReader streamReader = new StreamReader(stream, encoding: Encoding.UTF8);
                log.ResponseParam = await streamReader.ReadToEndAsync();
                streamReader.Close();
                stream.Close();
                log.LogType = "success";
            }
            catch (Exception ex)
            {
                log.LogType = "error:" + (ex.InnerException is null ? ex.Message : ex.InnerException.Message);
                log.ResponseParam = ex.Message;
            }
            finally
            {
                log.EndDate = DateTime.Now;
                try
                {
                    await _quartzService.AddTaskLog(log);
                }
                catch { }
            }
            return;
        }
    }
}
